package group_01.MultiSnakeServer;

import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
 * 
 * @author Martin Nume
 *The ServerEngine is the core of the serverprogram. Handles the Map with Games mapped to gameID
 */
public class ServerEngine {
	
	private final int NR_OF_WELCOMESERVERS;
	private final int START_WELCOMEPORT;
	
	
	private int gameID;
	
	private Map<String,GameHandler> gameList;
	
	public ServerEngine() {
		NR_OF_WELCOMESERVERS = 1;
		START_WELCOMEPORT = 7000;
		gameID = 1000;
		gameList = new HashMap<String,GameHandler>();
		startWelcomeServers();
		
		
		
	}
	
	/**
	 * Starts up the specified number of welcomeservers. 
	 */
	private void startWelcomeServers(){
		
		for(int i =0; i < NR_OF_WELCOMESERVERS; i++) {
			new WelcomeServer(this,START_WELCOMEPORT + i);
			
		}
		
		
	}
	
	/**
	 * A ToString representation of the Map containing all the games and gameIDs. 
	 * @return
	 */
	public String GameListToString() {
		String str ="get_list;"; 
		Iterator<Map.Entry<String, GameHandler>> it = gameList.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<String, GameHandler> entry = it.next();
			if(entry.getValue().getCurrentPlayers() < entry.getValue().getMaxPlayers()){
				str = str.concat(entry.getKey()).concat(";");//add gameID
				str = str.concat(entry.getValue().getGameName()).concat(";");// add gameName
				str = str.concat(entry.getValue().getCurrentPlayers() + ";" + entry.getValue().getMaxPlayers());// add currentPlayers/maxPlayers
				if(it.hasNext())
					str = str.concat(":");
			}
		}
		return str;
		
	}
	
	/**
	 * Returns a new unique gameID
	 * @return gameID
	 */
	private synchronized String getNewGameID() {
		
		return gameID++ +"";
	}
	
	/**
	 * Method to add a GameHandler to the Map of games
	 * @param gameHandler
	 * @return id of the added game
	 */
	public synchronized String AddGame(GameHandler gameHandler) {
		String id = getNewGameID();
		gameHandler.setGameID(id);
		gameList.put(id, gameHandler);
		return id;
		
	}
	
	/**
	 * Method to join a game
	 * 
	 * @param gameId
	 * @param playerName
	 * @param socket for the client to communicate with the server
	 * @return
	 */
	public synchronized boolean joinGame(String gameId, String playerName, Socket socket) {
		GameHandler gameHandler = gameList.get(gameId);
		if(gameHandler != null && (gameHandler.getCurrentPlayers() < gameHandler.getMaxPlayers())) {
			gameHandler.addPlayer(new PlayerHandler(playerName,socket));
			
			return true;
		}
		return false;
	}
	
	/**
	 * remove a game from the Map of games
	 * @param gameID
	 */
	public synchronized void RemoveGame(String gameID) {
		gameList.remove(gameID);
	}
	
}
